package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.apis.article.IArticleClient;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmCommentPageReqDTO;
import com.heima.model.wemedia.dtos.WmCommentRepayDTO;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.model.wemedia.vos.WmCommentVo;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.pojos.ApComment;
import com.heima.wemedia.pojos.ApCommentLike;
import com.heima.wemedia.pojos.ApCommentRepayLike;
import com.heima.wemedia.pojos.ApCommentReply;
import com.heima.wemedia.service.WmCommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author:Dikk
 * @create: 2023-08-03 10:04
 * @Description: WmCommentServiceImpl
 */
@Service
public class WmCommentServiceImpl implements WmCommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private IArticleClient articleClient;

    @Autowired
    private WmNewsMapper wmNewsMapper;


    /**
     * 自媒体端回复评论
     *
     * @param wmCommentRepayDTO
     * @return
     */
    @Override
    public ResponseResult commentRepay(WmCommentRepayDTO wmCommentRepayDTO) {

        //参数校验
        if (Objects.isNull(wmCommentRepayDTO)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //通过评论id查询评论信息
        ApComment apComment = mongoTemplate.findOne(new Query(Criteria.where("id").is(wmCommentRepayDTO.getCommentId())), ApComment.class);
        if (Objects.isNull(apComment)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //将文章的回复数量+1
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);

        //获取wmUser
        Integer wmUserId = WmThreadLocalUtil.getUser().getId();
        WmUser wmUser = wmUserMapper.selectById(wmUserId);

        //加入到评论回复表中
        ApCommentReply apCommentReply = new ApCommentReply();
        apCommentReply.setCommentId(apComment.getId());
        apCommentReply.setContent(wmCommentRepayDTO.getContent());
        apCommentReply.setAuthorId(wmUser.getId());
        apCommentReply.setLikes(0);
        apCommentReply.setAuthorName(wmUser.getName());
        apCommentReply.setCreatedTime(new Date());
        apCommentReply.setUpdatedTime(new Date());

        mongoTemplate.save(apCommentReply);

        // 评论增加一条到文章表中
        articleClient.addOneComment(apComment.getEntryId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除评论
     *
     * @param commentId
     * @return
     */
    @Override
    public ResponseResult deleteComment(String commentId) {
        //参数校验
        if (StringUtils.isBlank(commentId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //获取评论信息
        ApComment apComment = mongoTemplate.findOne(new Query(Criteria.where("id").is(commentId)), ApComment.class);
        if (Objects.isNull(apComment)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //获取总的评论数量
        List<ApCommentReply> commentReplyList = mongoTemplate.find(new Query(Criteria.where("commentId").is(commentId)), ApCommentReply.class);
        int commentNum = commentReplyList.size() + 1;

        //文章表中删除对应数量的评论
        articleClient.deleteCommentNum(commentNum, apComment.getEntryId());

        //获取评论集合
        List<ApComment> apCommentList = mongoTemplate.find(new Query(Criteria.where("id").is(commentId)), ApComment.class);

        //通过评论集合获取评论回复id集合
        List<String> apCommentIdList = apCommentList.stream().map(ApComment::getId).collect(Collectors.toList());
        List<String> commentRepayIdList = mongoTemplate.find(new Query(Criteria.where("commentId").in(apCommentIdList)), ApCommentReply.class)
                .stream().map(ApCommentReply::getId).collect(Collectors.toList());


        //判断评论回复集合是否为空
        if (commentRepayIdList != null && commentRepayIdList.size() > 0) {
            //删除评论回复点赞表数据
            mongoTemplate.remove(new Query(Criteria.where("commentRepayId").in(commentRepayIdList)), ApCommentRepayLike.class);
        }

        //删除评论
        mongoTemplate.remove(new Query(Criteria.where("id").is(commentId)), ApComment.class);

        //删除评论回复
        mongoTemplate.remove(new Query(Criteria.where("commentId").is(commentId)), ApCommentReply.class);

        //删除评论点赞表
        mongoTemplate.remove(new Query(Criteria.where("commentId").is(commentId)), ApCommentLike.class);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除评论回复
     *
     * @param commentRepayId
     * @return
     */
    @Override
    public ResponseResult deleteCommentRepay(String commentRepayId) {

        //参数校验
        if (StringUtils.isBlank(commentRepayId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //通过回复评论id获取
        ApCommentReply commentReply = mongoTemplate.findOne(new Query(Criteria.where("id").is(commentRepayId)), ApCommentReply.class);
        if (Objects.isNull(commentReply)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //删除评论回复点赞表数据
        mongoTemplate.remove(new Query(Criteria.where("commentRepayId").in(commentRepayId)), ApCommentRepayLike.class);

        //删除评论回复
        mongoTemplate.remove(new Query(Criteria.where("id").is(commentRepayId)), ApCommentReply.class);

        //获取articleId
        ApComment apComment = mongoTemplate.findOne(new Query(Criteria.where("id").is(commentReply.getCommentId())), ApComment.class);

        //更新apComment中的评论回复数量
        apComment.setReply(apComment.getReply() - 1);
        mongoTemplate.save(apComment);

        //文章表中数据更新评论数量
        articleClient.deleteCommentNum(1, apComment.getEntryId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    /**
     * 查看文章评论列表
     *
     * @param wmCommentPageReqDTO
     * @return
     */
    @Override
    public ResponseResult findNewsComments(WmCommentPageReqDTO wmCommentPageReqDTO) {
        //参数校验
        if (Objects.isNull(wmCommentPageReqDTO)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        wmCommentPageReqDTO.checkParam();
        //时间格式
        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        String beginDate = wmCommentPageReqDTO.getBeginDate();
        String endDate = wmCommentPageReqDTO.getEndDate();

        LocalDateTime beginTime = null;
        LocalDateTime endTime = null;

        //解析时间
        beginTime = LocalDateTime.of(LocalDate.parse(beginDate, format), LocalTime.MIN);
        endTime = LocalDateTime.of(LocalDate.parse(endDate, format), LocalTime.MAX);

        //判断文章是否是作者自己的
        Integer userId = WmThreadLocalUtil.getUser().getId();

        //通过userId自媒体作者自己所有的文章id
        LambdaQueryWrapper<WmNews> lambdaQueryWrapper = Wrappers.<WmNews>lambdaQuery()
                .eq(WmNews::getUserId, userId).lt(WmNews::getPublishTime, endTime)
                .eq(WmNews::getStatus, WmNews.Status.PUBLISHED.getCode())  //判断文章状态是已发布文章
                .gt(WmNews::getPublishTime, beginTime).orderByDesc(WmNews::getCreatedTime);

        //分页查询
        Page<WmNews> page = new Page<>(wmCommentPageReqDTO.getPage(), wmCommentPageReqDTO.getSize());
        page = wmNewsMapper.selectPage(page, lambdaQueryWrapper);
        List<WmNews> wmNews = page.getRecords();
        long total = page.getTotal();
        List<Long> articleIdList = wmNews.stream().map(WmNews::getArticleId).collect(Collectors.toList());

        List<WmCommentVo> wmCommentVos = new ArrayList<>();
        for (Long articleId : articleIdList) {
            if (articleId == null) {
                break;
            }
            WmCommentVo wmCommentVo = new WmCommentVo();

            //获取文章信息 通过feign远程调用
            ApArticle article = articleClient.getArticle(articleId);

            //获取该文章的所有评论信息
            List<ApComment> apComments = mongoTemplate.find(new Query(Criteria.where("entryId").is(articleId)), ApComment.class);

            //获取所有回复的和
            int sum = apComments.stream().map(ApComment::getReply).collect(Collectors.toList())
                    .stream().mapToInt(Integer::intValue).sum();

            //评论总数为  apComments.size() + sum
            int comments = sum + apComments.size();

            //获取文章配置信息 通过feign远程调用
            ResponseResult responseResult = articleClient.findArticleConfigByArticleId(articleId);
            String data = JSON.toJSONString(responseResult.getData());
            if (StringUtils.isBlank(data)) {
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
            }
            ApArticleConfig apArticleConfig = JSON.parseObject(data, ApArticleConfig.class);

            //封装wmCommentVo
            wmCommentVo.setIsComment(apArticleConfig.getIsComment());
            wmCommentVo.setId(articleId.toString());
            wmCommentVo.setComments(comments);
            wmCommentVo.setTitle(article.getTitle());

            //1623328043049
            wmCommentVo.setCreateTime((int) (article.getCreatedTime().getTime() / 1000));

            wmCommentVos.add(wmCommentVo);
        }
        ResponseResult result = new PageResponseResult((int) page.getCurrent(),
                (int) page.getSize(), (int) total);

        result.setData(wmCommentVos);
        return result;
    }
}
